package com.gitee.huanminabc.dynamicdb.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.gitee.huanminabc.dynamicdb.core.DynamicDataSource;
import lombok.Data;
import org.apache.ibatis.logging.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionManager;

import java.util.HashMap;
import java.util.Map;
/**
 * @author huanmin
 * @date 2024/11/22
 */
@Component
@Data
public class DynamicDataSourceMybatisConfig {

    @Autowired
    private DynamicDbSpringConfig dynamicDbSpringConfig;

    @Autowired
    private MybatisPlusConfig mybatisPlusConfig;





    /**
     * 动态数据源
     */
    @Bean(name = "abstractRoutingDataSource")
    @Primary //优先使用
    public DynamicDataSource dynamicDataSource() {
        DynamicDataSource dataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        dataSource.setTargetDataSources(targetDataSources);
        return dataSource;
    }


    //覆盖默认的事务管理器, 兼容@Transaction , 但是不支持跨数据源事务
    @Primary
    @Bean
    public TransactionManager transactionManager(@Autowired @Qualifier("abstractRoutingDataSource") AbstractRoutingDataSource abstractRoutingDataSource) {
        return new DataSourceTransactionManager(abstractRoutingDataSource);
    }


    /**
     * 会话工厂
     */
    @Bean
    public org.apache.ibatis.session.SqlSessionFactory sqlSessionFactoryBean(@Autowired @Qualifier("abstractRoutingDataSource") AbstractRoutingDataSource abstractRoutingDataSource) throws Exception {
        if (mybatisPlusConfig.getMapperLocations()==null){
            throw new RuntimeException("mybatisPlusConfig.mapperLocations 不能为空");
        }
        if (mybatisPlusConfig.getTypeAliasesPackage()==null){
            throw new RuntimeException("mybatisPlusConfig.typeAliasesPackage 不能为空");
        }
        //mybatis-plus 包含mybatis
        com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean();
        com.baomidou.mybatisplus.core.MybatisConfiguration configuration = new com.baomidou.mybatisplus.core.MybatisConfiguration();
        sqlSessionFactoryBean.setDataSource(abstractRoutingDataSource);
        sqlSessionFactoryBean.setConfiguration(configuration);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        MybatisPlusConfig.Configuration config = mybatisPlusConfig.getConfiguration();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mybatisPlusConfig.getMapperLocations()));
        sqlSessionFactoryBean.setTypeAliasesPackage(mybatisPlusConfig.getTypeAliasesPackage());
        configuration.setMapUnderscoreToCamelCase(config.isMapUnderscoreToCamelCase()); //开启驼峰命名
        if (config.getLogImpl() != null) {
            configuration.setLogImpl((Class<? extends Log>) Class.forName(config.getLogImpl())); //控制台打印sql日志
        }
        //插件类
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //分页插件, 自动识别数据库类型
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        //添加插件
        sqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor);
        return sqlSessionFactoryBean.getObject();
    }


}
